"解决程序健壮性拉流"

__author__ = "zwj"

# 导入根目录作为模块搜索路径
import os, sys

# ([".."] * 4) 就是项目目录里面 4 层
parent_path = os.path.abspath(os.path.join(__file__, *([".."] * 4)))
sys.path.insert(0, parent_path)

import cv2, time, traceback
from typing import Dict

from core.utils.logger import logging
from core.utils.error_exception import ErrorException

from core.task.modules.processors.steam_pull import SteamPull
from projects.GangHang.processors.http_message import HttpMessage
from projects.GangHang.processors.esdk import esdk


class SteamPullNew(SteamPull):
    def __init__(
        self,
        keys,
        SteamPull_url=None,
        SteamPull_size=None,
        SteamPull_fps=200,
        SteamPull_retry_time=5,
        HttpMessage_cfg_path=None,
    ) -> None:
        super().__init__(
            keys, SteamPull_url, SteamPull_size, SteamPull_fps, SteamPull_retry_time
        )

        self.__http_message = HttpMessage()
        self.__http_message.init_cfg(HttpMessage_cfg_path)

    def _set(self, data: Dict):
        # * 开启机场无人机直播流
        self.__http_message.live_stop()
        if not esdk.StartH264Stream():
            raise ErrorException("无人机直播流开启失败,可能是无人机未启动!")

        # false_count = 0
        # logging.info("开启无人机直播流...")
        # while True:
        #     if esdk.StartH264Stream():
        #         break
        #     else:
        #         false_count += 1
        #         self.__http_message.live_stop()
        #         if false_count > 5:
        #             raise ErrorException("无人机直播流开启失败,可能是无人机未启动!")
        # logging.info("无人机直播流开启完毕!")

        super()._set(data)

    def _close(self):
        esdk.StopH264Stream()
        super()._close()

    def video_read_loop(self):
        try:
            while True:
                time.sleep(1)
                if self.is_running():
                    break
                elif self.is_close():
                    break
                logging.info("{} waitting start....".format(self.__class__.__name__))

            retry_time = 0
            while self.is_running():
                ret, frame = self.cap.read()
                # 用于处理空帧
                if not ret:
                    ret, frame = self.cap.read()
                    if not ret:
                        ret, frame = self.cap.read()
                # ------
                if not ret:
                    retry_time += 1
                    if retry_time > self.retry_time:
                        raise Exception(
                            "cap retry more than {}, close this cap".format(
                                self.retry_time
                            )
                        )
                    logging.warning(
                        "|WAR: cap reading fail, waiting 2s and retry {}|".format(
                            retry_time
                        )
                    )
                    # 开关 esdk 拉流功能
                    esdk.StopH264Stream()
                    self.__http_message.live_stop()
                    esdk.StartH264Stream()

                    time.sleep(2)
                    self.cap = cv2.VideoCapture(self.pull_url)
                    continue

                retry_time = 0
                self.frame = cv2.resize(frame, self.pull_size)
                time.sleep(1 / self.fps)

        except Exception:
            logging.error(traceback.format_exc())
            self.close()
        finally:
            logging.info("|SteamPull.video_read_loop done|")
